package io.yyxx.boot.business.service.impl;

import cn.hutool.json.JSONUtil;
import io.yyxx.boot.business.entity.billDataEntity.FlightBillData;
import io.yyxx.boot.business.vo.FlightBillResponseVo;
import io.yyxx.boot.util.DateTimeToTimestampUtil;
import io.yyxx.boot.util.SaveDataToYiDa;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class Flight {

    @Resource
    private SaveDataToYiDa saveDataToYiDa;
    @Resource
    private FlightBillDataServiceImpl flightBillDataServiceImpl;

    public void saveTrainBillToYiDa() {
        List<FlightBillResponseVo> responseVoToYiDa;
        //从数据库中查询航班账单数据
        List<FlightBillData> flightBillData = flightBillDataServiceImpl.selectFlightBillData();

        // 将筛选后的数据映射到 ResponseVo 对象中，并拼接时间字符串
        responseVoToYiDa = flightBillData.stream()
                .map(data -> {
                    FlightBillResponseVo vo = new FlightBillResponseVo();
                    ArrayList<String> travelerId = new ArrayList<>();
                    ArrayList<String> dept = new ArrayList<>();
                    ArrayList<String> time = new ArrayList<>();

                    // 拼接出发时间（deptDate + deptTime）
                    String startTime = "";
                    if (data.getDeptDate() != null && data.getDeptTime() != null) {
                        startTime = data.getDeptDate() + " " + data.getDeptTime();
                    }

                    // 拼接到达时间（arrDate + arrTime）
                    String endTime = "";
                    if (data.getArrDate() != null && data.getArrTime() != null) {
                        endTime = data.getArrDate() + " " + data.getArrTime();
                    }

                    //其他不用拼接的变量，将时间转为时间戳
                    String startTimestamp = DateTimeToTimestampUtil.DateTimeToTimestamp2(startTime) + "";
                    String endTimestamp = DateTimeToTimestampUtil.DateTimeToTimestamp2(endTime) + "";
                    time.add(startTimestamp);
                    time.add(endTimestamp);
                    vo.setTime(time);                                //时间区间

                    vo.setDeptStation(data.getDeptStation());       // 出发站
                    vo.setArrStation(data.getArrStation());         // 到达站
                    vo.setFlightNo(data.getFlightNo());             // 航班号

                    travelerId.add(data.getTravelerId());
                    vo.setTravelerId(travelerId);                    //  出差人id
                    dept.add(data.getDepartmentId());
                    vo.setPaymentDepartmentId(dept);               // 费用归属部门id
                    vo.setSettlementFee(data.getSettlementFee());  // 航班结算金额
                    String bookTime = DateTimeToTimestampUtil.DateTimeToTimestamp2(data.getBookTime()) + "";
                    vo.setBookTime(bookTime);                     // 预订时间
                    vo.setProjectName(data.getProjectName());   // 项目名称
                    vo.setProjectCode(data.getProjectCode());   // 项目编码
                    vo.setApplyId(data.getApplyId());           // 审批单号
                    vo.setState("未报销");                        //设置状态
                    vo.setCostCenter(data.getCostCenter());    // 成本中心
                    vo.setCostCenterNumber(data.getCostCenterNumber());// 成本中心编码

                    vo.setFeeTypeDesc(data.getFeeTypeDesc());// 费用类型描述
                    vo.setSettleTypeDesc(data.getSettleTypeDesc());//结算类型描述

                    return vo;
                })
                .collect(Collectors.toList());
        // ========== 新增：航班账单合并功能开始 ==========
// 1. 按flightNo分组（仅处理flightNo不为空的数据）
        Map<String, List<FlightBillResponseVo>> flightNoGroup = responseVoToYiDa.stream()
                // 强转类型为FlightBillResponseVo（因responseVoToYiDa泛型可能为父类）
                .map(vo -> (FlightBillResponseVo) vo)
                // 新增：过滤掉settleTypeDesc为"个人现付"的记录
                .filter(vo -> !"个人现付".equals(vo.getSettleTypeDesc()))
                // 过滤掉flightNo为空的记录（无需合并）
                .filter(vo -> vo.getFlightNo() != null && !vo.getFlightNo().trim().isEmpty())
                // 按flightNo分组
                .collect(Collectors.groupingBy(FlightBillResponseVo::getFlightNo));

// 2. 处理每个分组：合并数据并保留目标记录
        List<FlightBillResponseVo> mergedResult = new ArrayList<>();
        for (List<FlightBillResponseVo> group : flightNoGroup.values()) {
            // 2.1 从分组中找到feeTypeDesc为"机票预订"的记录（主记录）
            FlightBillResponseVo mainVo = group.stream()
                    .filter(vo -> "机票预订".equals(vo.getFeeTypeDesc()))
                    .findFirst()
                    .orElse(null);

            // 2.2 如果存在"机票预订"记录（主记录）
            if (mainVo != null) {
                // 计算非"机票预订"记录的settlementFee总和，用于设置serviceFee
                double totalServiceFee = group.stream()
                        .filter(vo -> !"机票预订".equals(vo.getFeeTypeDesc()))
                        .mapToDouble(FlightBillResponseVo::getSettlementFee)
                        .sum();

                // 仅将非"机票预订"记录的settlementFee设为0
                group.stream()
                        .filter(vo -> !"机票预订".equals(vo.getFeeTypeDesc()))
                        .forEach(vo -> vo.setSettlementFee(0.0));

                // 主记录设置serviceFee，保留自身settlementFee原值
                mainVo.setServiceFee(String.valueOf(totalServiceFee));
                mergedResult.add(mainVo); // 只保留主记录
            }
            // 2.3 如果不存在"机票预订"记录，保留第一条作为主记录，并将其settlementFee设为0
            else if (!group.isEmpty()) {
                FlightBillResponseVo firstVo = group.get(0); // 第一条作为主记录

                // 计算所有记录的settlementFee总和（包括第一条），用于设置serviceFee
                double totalServiceFee = group.stream()
                        .mapToDouble(FlightBillResponseVo::getSettlementFee)
                        .sum();

                // 拼接所有记录的feeTypeDesc（包括第一条）
                String mergedFeeTypes = group.stream()
                        .map(vo -> vo.getFeeTypeDesc() != null ? vo.getFeeTypeDesc() : "")
                        .filter(feeType -> !feeType.isEmpty())
                        .distinct()
                        .collect(Collectors.joining("、"));

                // 将第一条记录（主记录）的settlementFee设为0
                firstVo.setSettlementFee(0.0);

                // 主记录设置serviceFee和合并后的feeTypeDesc
                firstVo.setServiceFee(String.valueOf(totalServiceFee));
                firstVo.setFeeTypeDesc(mergedFeeTypes);
                mergedResult.add(firstVo); // 只保留第一条主记录
            }
        }

// 3. 补充flightNo为空的记录（不参与合并，直接保留）
        List<FlightBillResponseVo> nonFlightNoRecords = responseVoToYiDa.stream()
                // 强转类型为FlightBillResponseVo
                .map(vo -> (FlightBillResponseVo) vo)
                .filter(vo -> vo.getFlightNo() == null || vo.getFlightNo().trim().isEmpty())
                .collect(Collectors.toList());

// 4. 合并最终结果：合并后的数据 + 不参与合并的flightNo为空的数据
        mergedResult.addAll(nonFlightNoRecords);

// 5. 用合并后的结果替换原responseVoToYiDa（转回父类泛型）
        responseVoToYiDa = new ArrayList<>(mergedResult);
// ========== 新增：航班账单合并功能结束 ==========

        for (FlightBillResponseVo flightBillResponseVo : responseVoToYiDa) {
            //转成josn格式
            String jsonStr = JSONUtil.toJsonStr(flightBillResponseVo);
            //调用SendData发送至宜搭
            try {
                saveDataToYiDa.saveData(jsonStr);
                log.info("航班账单数据jsonStr:" + jsonStr);
                log.info("航班账单数据发送成功");
            } catch (Exception e) {
                log.error("航班账单数据向宜搭发送失败" + e);
                throw new RuntimeException(e);
            }
        }
    }
}
